package  
{
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	
	/**
	 * ...
	 * @author 
	 */
	public class Main extends MovieClip 
	{
		private static const _ROW_		:int = 6;
		private static const _COLUMN_	:int = 10;
		
		private static const _SPACE		:int = 5;
		
		private static const _NUM_OF_SAMPLE	:int = 15;
		
		private var arrValue	:Array;
		private var arrItem		:Array;
		
		private var matrix		:Array;
		
		private var mcItem1		:MovieClip;
		private var mcItem2		:MovieClip;
		
		public function Main() 
		{
			initGame();
		}
		
		private function initGame():void 
		{
			arrValue = [];
			arrItem = [];
			
			mcItem1 = null;
			mcItem2 = null;
			
			var i:int;
			var j:int;
			
			// init matrix
			matrix = new Array(_ROW_ + 2);
			var arrChild:Array;
			
			for (i = 0; i < matrix.length; i++)
			{
				arrChild = new Array(_COLUMN_ + 2);
				
				for (j = 0; j < arrChild.length; j++)
				{
					if ( (i == 0) || (i == matrix.length - 1) || (j == 0) || (j == arrChild.length - 1 ) )
					{
						arrChild[j] = 0;
					} else
					{
						arrChild[j] = 1;
					}
				}
				
				matrix[i] = arrChild;
			}
			
			// init value array
			for (i = 0; i < _ROW_ * _COLUMN_; i++)
			{
				arrValue[i] = 0;
			}
			
			// set value of array & matrix
			var arrPos:Array = [];
			
			for (i = 0; i < arrValue.length; i++)
			{
				arrPos[i] = i;
			}
			
			var pos:int = 0;
			var index:int = 0;
			
			while (arrPos.length > 0)
			{
				for (i = 0; i < _NUM_OF_SAMPLE; i++)
				{
					if (arrPos.length == 0)
					{
						return;
					}
					
					pos = Math.floor(Math.random() * arrPos.length);
					arrValue[arrPos[pos]] = i + 1;
					arrPos.splice(pos, 1);
				}
			}
			
			var col:int;
			var row:int;
			
			for (i = 0; i < arrValue.length; i++)
			{
				row = Math.floor(i / _COLUMN_);
				col = i % _COLUMN_;
				
				matrix[row + 1][col + 1] = arrValue[i];
			}
			
			
			
			
			// init Item array
			var mcItem:MovieClip;
			
			for (i = 0; i < _ROW_ * _COLUMN_; i++)
			{
				mcItem = new ItemFC();
				mcItem.value = parseInt(arrValue[i]);
				
				mcItem.col = i % _COLUMN_ + 1;
				mcItem.row = Math.floor(i / _COLUMN_) + 1;
				
				mcItem.txtLabel.text = arrValue[i];
				
				arrItem.push(mcItem);
				
				mcContainer.addChild(mcItem);
				
				mcItem.x = (mcItem.width + _SPACE) * (i % _COLUMN_);
				mcItem.y = (mcItem.height + _SPACE) * Math.floor(i / _COLUMN_);
				
				mcItem.addEventListener(MouseEvent.CLICK, onClickCard);
			}
			
			mcContainer.x = stage.stageWidth / 2 - mcContainer.width / 2;
			mcContainer.y = stage.stageHeight / 2 - mcContainer.height / 2;
		}
		
		private function onClickCard(e:MouseEvent):void 
		{
			var item:MovieClip = e.currentTarget as MovieClip;
			
			if (mcItem1 == null)
			{
				mcItem1 = item;
				mcItem1.gotoAndStop(2);
			} else
			{
				mcItem2 = item;
				
				if (mcItem1 != mcItem2)
				{
					if (mcItem1.value == mcItem2.value)
					{
						if (checkPosition(mcItem1.row, mcItem1.col, mcItem2.row, mcItem2.col))
						{
							mcContainer.removeChild(mcItem1);
							mcContainer.removeChild(mcItem2);
							
							matrix[mcItem1.row][mcItem1.col] = 0;
							matrix[mcItem2.row][mcItem2.col] = 0;
							
							//for (var i = 0; i < matrix.length; i++)
							//{
								//trace(matrix[i]);
							//}
						}
					} else {
						// unselect
					}
				}
				
				mcItem1.gotoAndStop(1);
				mcItem2.gotoAndStop(1);
				
				mcItem1 = null;
				mcItem2 = null;
			}
		}
		
		private function isFillAround(row:int, col:int):Boolean 
		{
			if (matrix[row][col - 1] == 0)
			{
				return false;
			}
			if (matrix[row][col + 1] == 0)
			{
				return false;
			}
			
			if (matrix[row - 1][col] == 0)
			{
				return false;
			}
			if (matrix[row + 1][col] == 0)
			{
				return false;
			}
			
			return true;
		}
		
		private function checkPosition(row1:int, col1:int, row2:int, col2:int):Boolean 
		{
			var result:Boolean = false;
			
			var numRow	:int = Math.abs(row1 - row2);
			var numCol	:int = Math.abs(col1 - col2);
			
			var i:int = 0;
			var j:int = 0;
			
			if ( isFillAround(mcItem1.row, mcItem1.col) || isFillAround(mcItem2.row, mcItem2.col) )
			{
				if ( ( (numRow == 1) && (numCol == 0) ) || ( (numRow == 0) && (numCol == 1) ) )
				{
					return true;
				}
				
				return false;
			}
			
			// horizon
			if (numRow == 0)
			{
				// col1           col2
				//  -  -  -  -  -  -
				//  -  -  -  -  -  -
				//  1  0  0  0  0  1   ==> row1 = row2
				//  -  -  -  -  -  -
				//  -  -  -  -  -  -
				
				result = checkHorizon(row1, col1, row2, col2);
			}
			else if (numCol == 0)
			{
				//       col
				//  -  -  1  -  - ==> row1
				//  -  -  0  -  -
				//  -  -  0  -  -
				//  -  -  0  -  -
				//  -  -  1  -  - ==> row2
				
				result = checkVertical(row1, col1, row2, col2);
			} 
			else
			{
				result = checkHorizon(row1, col1, row2, col2);
				if (result) {
					return result;
				}
				
				result = checkVertical(row1, col1, row2, col2);
			}
			
			return result;
		}
		
		private function checkHorizon(row1:int, col1:int, row2:int, col2:int):Boolean
		{
			var checkv1:Boolean = false;
			var checkh:Boolean = false;
			var checkv2:Boolean = false;
			
			var i:int;
			var j:int;
			
			// col1           col2
			//  -  -  -  -  -  -
			//  -  -  -  -  -  1   ==> row2
			//  -  -  -  -  -  0
			//  0  0  0  0  0  0
			//  0  -  -  -  -  -
			//  1  -  -  -  -  -   ==> row1
			//  -  -  -  -  -  -
			
			
			for (i = row1 - 1; i >= 0; i --) 
			{
				checkv1 = checkCol(col1, row1, i);
				checkh = checkRow(i, col1, col2);
				checkv2 = checkCol(col2, i, row2);
				
				if (checkv1 && checkh && checkv2) {
					trace('up', checkv1, checkh, checkv2);
					return true;
				}
			}
			
			// col1           col2
			//  -  -  -  -  -  -
			//  -  -  -  -  -  1   ==> row2
			//  -  -  -  -  -  0
			//  -  -  -  -  -  0
			//  1  -  -  -  -  0  ==> row1
			//  0  -  -  -  -  0  
			//  0  0  0  0  0  0
			
			for (i = row1 + 1; i < matrix.length; i ++) {						
				checkv1 = checkCol(col1, row1, i);						
				checkh = checkRow(i, col1, col2);
				checkv2 = checkCol(col2, i, row2);
				

				if (checkv1 && checkh && checkv2) {							
					//trace('down', checkv1, checkh, checkv2);					
					return true;
				}
			}
			
			return false;
		}
		
		private function checkVertical(row1:int, col1:int, row2:int, col2:int):Boolean
		{
			var checkh1:Boolean = false;
			var checkv:Boolean = false;
			var checkh2:Boolean = false;
			
			var i:int;
			var j:int;
			
			//    col1        col2
			//  -  -  -  -  -  -
			//  0  0  0  0  0  1   ==> row2
			//  0  -  -  -  -  -
			//  0  -  -  -  -  -
			//  0  1  -  -  -  -   ==> row1
			//  -  -  -  -  -  -
			
			for (j = col1 - 1; j >= 0; j --) {
				checkh1 = checkRow(row1, col1, j);
				checkv = checkCol(j, row1, row2);
				checkh2 = checkRow(row2, j, col2);
				
				if (checkh1 && checkv && checkh2) {
					//trace('left', checkh1, checkv, checkh2);
					return true;
				}
			}
			
			// col1           col2
			//  -  -  -  -  -  -
			//  -  -  0  0  0  1   ==> row2
			//  -  -  0  -  -  -
			//  -  -  0  -  -  -
			//  1  0  0  -  -  -   ==> row1
			//  -  -  -  -  -  -
			
			for (j = col1 + 1; j < matrix[0].length; j ++) {
				checkh1 = checkRow(row1, col1, j);					
				checkv = checkCol(j, row1, row2);
				checkh2 = checkRow(row2, j, col2);
				
				if (checkh1 && checkv && checkh2) {
					//trace('right', checkh1, checkv, checkh2);
					return true;
				}
			}
			
			return false;
		}
		
		private function checkRow(row:int, start:int, end:int):Boolean { 
			if (start == end) {
				return true;
			}
			
			//  -  -  -  -  -  -
			//  -  -  -  -  -  -
			//  1  0  0  0  0  1 ==> row
			//  -  -  -  -  -  -
			//  -  -  -  -  -  -
			// start          end
			
			if (start > end) {
				var temp:int = end;
				end = start;
				start = temp;
			}
			
			//trace("start check row: (" + row + ', ' + start + ') to (' + row + ', ' + end + ')');
			for (var j:int = start + 1; j < end; j ++) 
			{
				if (matrix[row][j] != 0) {
					//trace("end row");
					return false;
				}
			}
			
			//trace("end row");			
			return true;			
		}
		
		private function checkCol(col:int, start:int, end:int):Boolean {			
			
			//       col
			//  -  -  1  -  -  - ==> start
			//  -  -  0  -  -  -
			//  -  -  0  -  -  - 
			//  -  -  0  -  -  -
			//  -  -  1  -  -  - ==> end
			
			if (start == end) {
				return true;
			}
			
			if (start > end) {
				var temp:int = end;
				end = start;
				start = temp;
			}
			
			//trace("start check col: (" + start + ', ' + col + ') to (' + end + ', ' + col + ')');
			
			for (var i:int = start + 1; i < end; i ++) {
				
				if (matrix[i][col] != 0) {
					//trace("end col");
					//trace();
					return false;
				}
			}
			
			//trace("end col");
			//trace();
			return true;
		}
		
		private function traceMatrix():void 
		{
			for (var i = 0; i < matrix.length; i++)
			{
				trace(matrix[i]);
			}
		}
	}

}
